package com.atguigu.controller;

import com.atguigu.client.OrderFeignClient;
import com.atguigu.client.UserFeignClient;
import com.atguigu.constant.MqConst;
import com.atguigu.constant.RedisConst;
import com.atguigu.entity.*;
import com.atguigu.result.RetVal;
import com.atguigu.result.RetValCodeEnum;
import com.atguigu.service.SeckillProductService;
import com.atguigu.util.AuthContextHolder;
import com.atguigu.util.MD5;
import com.atguigu.utils.DateUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

@RestController
@RequestMapping("/seckill")
public class SecKillController {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private UserFeignClient userFeignClient;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private SeckillProductService seckillProductService;
    @Autowired
    private OrderFeignClient orderFeignClient;

    //1.查询所有的秒杀商品列表
    @GetMapping("queryAllSeckillProduct")
    public RetVal queryAllSeckillProduct(){
        List<SeckillProduct> seckillProductList=redisTemplate.boundHashOps(RedisConst.SECKILL_PRODUCT).values();
        return RetVal.ok(seckillProductList);
    }
    //2.秒杀商品详情页面编写
    @GetMapping("getSecKillProductBySkuId/{skuId}")
    public RetVal getSecKillProductBySkuId(@PathVariable Long skuId){
        SeckillProduct seckillProduct= seckillProductService.getSecKillProductBySkuId(skuId);
        return RetVal.ok(seckillProduct);
    }
    //3.生成抢购码 防止用户直接跳过商品详情进入秒杀地址
    @GetMapping("generateSeckillCode/{skuId}")
    public RetVal generateSeckillCode(@PathVariable Long skuId, HttpServletRequest request){
        //b.判断用户是否登录
        String userId = AuthContextHolder.getUserId(request);
        if(StringUtils.isNotEmpty(userId)){
            //c.从缓存中查询秒杀商品信息
            SeckillProduct seckillProduct= seckillProductService.getSecKillProductBySkuId(skuId);
            //d.当前时间如果在秒杀时间范围之内 则生成抢购码
            Date currentTime = new Date();
            if(DateUtil.dateCompare(seckillProduct.getStartTime(),currentTime)&&
                    DateUtil.dateCompare(currentTime,seckillProduct.getEndTime())){
                //e.抢购码最好加个密
                String secKillCode = MD5.encrypt(userId);
                return RetVal.ok(secKillCode);
            }
        }
        return RetVal.fail().message("获取抢购码失败，请先登录");
    }
    //4.秒杀预下单
    @PostMapping("prepareSeckill/{skuId}")
    public RetVal prepareSeckill(@PathVariable Long skuId, String seckillCode,HttpServletRequest request){
        //a.抢购码是否匹配
        String userId = AuthContextHolder.getUserId(request);
        if(!MD5.encrypt(userId).equals(seckillCode)){
            //当预下单的时候用户不匹配 报异常
            return RetVal.build(null, RetValCodeEnum.SECKILL_ILLEGAL);
        }
        //b.该商品是否可以秒杀 状态位是正常(1)
        String state=(String)redisTemplate.opsForValue().get(RedisConst.SECKILL_STATE_PREFIX+skuId);
        if(StringUtils.isEmpty(state)){
            return RetVal.build(null, RetValCodeEnum.SECKILL_ILLEGAL);
        }
        //可以进行秒杀
        if(RedisConst.CAN_SECKILL.equals(state)){
            //c.把秒杀用户id和商品skuId发送消息给rabbitmq(等会儿处理)
            UserSeckillSkuInfo userSeckillSkuInfo = new UserSeckillSkuInfo();
            userSeckillSkuInfo.setUserId(userId);
            userSeckillSkuInfo.setSkuId(skuId);
            rabbitTemplate.convertAndSend(MqConst.PREPARE_SECKILL_EXCHANGE,MqConst.PREPARE_SECKILL_ROUTE_KEY,userSeckillSkuInfo);
        }else{
            //秒杀商品已经卖完
            return RetVal.build(null, RetValCodeEnum.SECKILL_FINISH);
        }
        return RetVal.ok();
    }

    //5.判断用户是否有抢购资格
    @GetMapping("hasQualified/{skuId}")
    public RetVal hasQualified(@PathVariable Long skuId, HttpServletRequest request){
        String userId = AuthContextHolder.getUserId(request);
        return seckillProductService.hasQualified(skuId,userId);
    }

    //6.秒杀确认订单信息
    @GetMapping("seckillConfirm")
    public RetVal seckillConfirm(HttpServletRequest request){
        String userId = AuthContextHolder.getUserId(request);
        //a.秒杀到的预售商品订单信息
        PrepareSeckillOrder prepareSeckillOrder=(PrepareSeckillOrder)redisTemplate.boundHashOps(RedisConst.PREPARE_SECKILL_USERID_ORDER).get(userId);
        if(prepareSeckillOrder==null){
            return RetVal.fail().message("非法请求");
        }
        //b.获取用户的收货地址
        List<UserAddress> userAddressList = userFeignClient.getAddressByUserId(userId);
        //c.用户秒到的那个商品
        SeckillProduct seckillProduct = prepareSeckillOrder.getSeckillProduct();
        //d.秒杀商品的订单明细
        OrderDetail orderDetail = new OrderDetail();
        orderDetail.setSkuId(seckillProduct.getSkuId());
        orderDetail.setSkuName(seckillProduct.getSkuName());
        orderDetail.setImgUrl(seckillProduct.getSkuDefaultImg());
        orderDetail.setSkuNum(prepareSeckillOrder.getBuyNum()+"");
        orderDetail.setOrderPrice(seckillProduct.getCostPrice());
        List<OrderDetail> orderDetailList = new ArrayList<>();
        orderDetailList.add(orderDetail);
        //e.返回数据给页面
        Map<String, Object> retMap = new HashMap<>();
        retMap.put("userAddressList",userAddressList);
        retMap.put("orderDetailList",orderDetailList);
        retMap.put("totalMoney",seckillProduct.getCostPrice());
        return RetVal.ok(retMap);
    }
    //7.提交秒杀订单信息
    @PostMapping("submitSecKillOrder")
    public RetVal submitSecKillOrder(@RequestBody OrderInfo orderInfo,HttpServletRequest request){
        String userId = AuthContextHolder.getUserId(request);
        //a.判断用户是否有预下单
        PrepareSeckillOrder prepareSeckillOrder=(PrepareSeckillOrder)redisTemplate.boundHashOps(RedisConst.PREPARE_SECKILL_USERID_ORDER).get(userId);
        if(prepareSeckillOrder==null){
            return RetVal.fail().message("非法操作");
        }
        //b.远程调用shop-order微服务
        Long orderId = orderFeignClient.saveOrderInfo(orderInfo);
        if(orderId==null){
            return RetVal.fail().message("下单失败");
        }
        //c.根据用户userId删除预订单
        redisTemplate.boundHashOps(RedisConst.PREPARE_SECKILL_USERID_ORDER).delete(userId);
        //d.把用户购买的商品信息保存到缓存当中 用于判断用户是否购买过商品
        redisTemplate.boundHashOps(RedisConst.BOUGHT_SECKILL_USER_ORDER).put(userId,orderId);
        return RetVal.ok(orderId);
    }



}
